#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<string.h>
#include<assert.h>

#define Identifier "$"
#define Separator " "
#define LINE_SIZE 1024
#define EXIT_CODE 99 

extern char** environ;
char command[LINE_SIZE];
char* substringset[10];
int last_code = 0;
int quit = 0;
int argc = 0;
char pwd[LINE_SIZE];
char myenv[LINE_SIZE][LINE_SIZE];
int envi = 0;

char* getname()
{
    return getenv("USER");
}

char* gethostname()
{
    return getenv("HOSTNAME");
}

void getpwd()
{
    getcwd(pwd, sizeof(pwd)); 
}

void interaction()
{
    //1.打印交互界面 2.从stein文件读取数据,读到command数组
    getpwd();
    printf("[%s@%s %s]"Identifier" ", getname(), gethostname(), pwd);
    //scanf("%s\n", command);
    //scanf读取不了空格，所以考虑使用fgets
    char* s = fgets(command, sizeof(command), stdin);
    assert(s != NULL);
    (void)s;
    command[strlen(command)-1]='\0';
     
//if(s)
//{
//    printf("%s\n", command);
//}
}

void Splitstring()
{
   //"ls -l -a" -> "ls" "-a" "-l"
   //因为要对字符串进行切割，所以需要一个指针数组
    int i = 0;
    char* substring = strtok(command, Separator);    
    substringset[i++] = substring; 
    while(substring = strtok(NULL, Separator))
    {
        substringset[i++] = substring;
    }
    argc = i;
    
    //for(int i = 0; substringset[i]; i++)
    //{
    //    printf("%s\n", substringset[i]);
    //}
}

int Commandjudgment()
{
    if(argc == 2 && strcmp(substringset[0], "cd") == 0)
    {
        //在更改当前目录的环境下环境变量如何更改
        chdir(substringset[1]);
        getpwd();
        sprintf(getenv("PWD"), "%s", pwd);
        return 1;
    }

    if(argc == 2 && strcmp(substringset[0], "export") == 0)
    {
        //putenv只是把环境变量表里面的指针指向后面你要添加的字符串，并没有把字符串内容添加到环境变量中
        strcpy(myenv[envi], substringset[1]); 
        putenv(myenv[envi++]);

        return 1;
    }

    if(argc == 2 && strcmp(substringset[0], "echo") == 0)
    {
        if(substringset[1][0] == '$')
        {
            char* val = getenv(substringset[1][1]);
            if(val)
            {
                printf("%s\n", getenv(substringset[1][1]));
            }
        }
        else if(strcmp(substringset[1], "$?") == 0)
        {
            printf("%d\n", last_code);
        }
        else
        {
            printf("%s\n", substringset[1]);
        }

        return 1; 
    }

    //让ls加上彩色
    if(strcmp(substringset[0], "ls") == 0)
    {
        substringset[argc++] = "--color";
        substringset[argc] = NULL;
        return 0;
    }

    return 0;
}

void Normalcommand()
{
    pid_t id = fork();
    if(id < 0)
    {
        perror("fork\n");
        return ;
    }
    else if(id == 0)
    {
        //child
        execvp(substringset[0], substringset);      
        exit(EXIT_CODE);
    }
    //这里一定记得要等待，要不然
    int status = 0;
    pid_t ret = waitpid(id, &status, 0);
    if(ret > 0)
    {
        last_code = WEXITSTATUS(status);
    }
} 

int main()
{
    while(!quit)
    {
        //1.交互界面
        interaction();
        //2.分割字符串
        Splitstring();
        //3.指令的判断：内建命令的执行
        int n = Commandjudgment();
       //4.常规命令的执行 
        if(n == 0)
        {
            Normalcommand();
        }
    }

    return 0;
}
